package com.umakr.ax.utils;

import com.umakr.ax.core.Constants;
import com.baomidou.mybatisplus.plugins.Page;
import com.umakr.ax.core.filter.CurrentHttpRequestFilter;
import com.umakr.ax.core.mybatis.proxy.PageCustom;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.ResourceBundle;


/**
 * Web层辅助类
 *
 * @author umakr
 */
public final class WebUtil  implements ApplicationContextAware {
    private static WebUtil webUtil = new WebUtil();
    public static WebUtil getInstance(){
        return webUtil;
    }
    private static ApplicationContext context = null;
    private static Log logger = LogFactory.getLog(WebUtil.class);
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    private WebUtil() {
    }


    /**
     * 根据名称获取bean
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName) {
        return context.getBean(beanName);
    }

    /**
     * 根据bean名称获取指定类型bean
     * @param beanName bean名称
     * @param clazz 返回的bean类型,若类型不匹配,将抛出异常
     */
    public static <T> T getBean(String beanName, Class<T> clazz) {
        return context.getBean(beanName, clazz);
    }
    /**
     * 根据类型获取bean
     * @param clazz
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        T t = null;
        Map<String, T> map = context.getBeansOfType(clazz);
        for (Map.Entry<String, T> entry : map.entrySet()) {
            t = entry.getValue();
        }
        return t;
    }
    public static Map<String,Object> getBeanWithAnnotation(Class<? extends Annotation> annotation){
        return context.getBeansWithAnnotation(annotation);
    }
    /**
     * 是否包含bean
     * @param beanName
     * @return
     */
    public static boolean containsBean(String beanName) {
        return context.containsBean(beanName);
    }

    /**
     * 是否是单例
     * @param beanName
     * @return
     */
    public static boolean isSingleton(String beanName) {
        return context.isSingleton(beanName);
    }

    /**
     * bean的类型
     * @param beanName
     * @return
     */
    public static Class getType(String beanName) {
        return context.getType(beanName);
    }


    /**
     * 获取指定Cookie的值
     * 
     * @param cookieName cookie名字
     * @param defaultValue 缺省值
     * @return
     */
    public static final String getCookieValue(String cookieName, String defaultValue) {
        Cookie cookie = WebUtils.getCookie(request(), cookieName);
        if (cookie == null) {
            return defaultValue;
        }
        return cookie.getValue();
    }

    /** 保存当前用户 */
//    public static final void saveCurrentUser(Object user) {
////        setSession(Constants.CURRENT_USER, user);
//    }

    /** 保存当前用户 */
    public static final void saveCurrentUser( Object user) {
        setSession(Constants.CURRENT_USER, user);
    }

    /** 获取当前用户 */
//    public static final Long getCurrentUser() {
//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//        if(authentication.isAuthenticated()){
//            BaseUser defaultEUser =  (BaseUser)authentication.getDetails();
//            return Long.parseLong(defaultEUser.getUserId());
//        }
//        return null;
//    }

    /** 获取当前用户 */
    public static final Object getCurrentUser() {
       HttpSession session = request().getSession();
            if (null != session) {
                    return session.getAttribute(Constants.CURRENT_USER);
            }
        return null;
    }

    /**
     * 将一些数据放到ShiroSession中,以便于其它地方使用
     * 
     */
//    public static final void setSession(Object key, Object value) {
//        Subject currentUser = SecurityUtils.getSubject();
//        if (null != currentUser) {
//            Session session = currentUser.getSession();
//            if (null != session) {
//                session.setAttribute(key, value);
//            }
//        }
//    }

    /**
     */
    public static final void setSession(String key, Object value) {
        HttpSession session = request().getSession();
        if (null != session) {
            session.setAttribute(key, value);
        }
    }

    /** 移除当前用户 */
    public static final void removeCurrentUser() {
        request().getSession().removeAttribute(Constants.CURRENT_USER);
    }

    /**
     * 获得国际化信息
     * 
     * @param key 键
     * @param request
     * @return
     */
    public static final String getApplicationResource(String key, HttpServletRequest request) {
        ResourceBundle resourceBundle = ResourceBundle.getBundle("ApplicationResources", request.getLocale());
        return resourceBundle.getString(key);
    }

    /**
     * 获得参数Map
     * 
     * @param request
     * @return
     */
    public static final Map<String, Object> getParameterMap(HttpServletRequest request) {
        return WebUtils.getParametersStartingWith(request, null);
    }

    /** 获取客户端IP */
    public static final String getHost(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        String unknown = "unknown";
        if (StringUtils.isBlank(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (StringUtils.isBlank(ip) || unknown.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("127.0.0.1".equals(ip)) {
            InetAddress inet = null;
            try { // 根据网卡取本机配置的IP
                inet = InetAddress.getLocalHost();
            } catch (UnknownHostException e) {
                logger.error(e);
            }
            ip = inet.getHostAddress();
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return ip;
    }

    public static boolean isAjax(HttpServletRequest request){
        String uri = request.getRequestURI();
        String accept = request.getHeader("Accept");
        return StringUtils.isNotEmpty(request.getHeader("x-requested-with"))||(accept!=null&&!(accept.contains("text/html")||accept.contains("*/*")))||uri.endsWith(".json")||uri.endsWith(".xml")||uri.endsWith(".js");
    }
    public static HttpServletRequest request(){
        if(CurrentHttpRequestFilter.getCurrentHttp()!=null){
            return CurrentHttpRequestFilter.getCurrentHttp().first;

        }
        return null;
    }

    public static String getBody(HttpServletRequest request) throws IOException {

        String body = null;
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;

        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }

        body = stringBuilder.toString();
        return body;
    }
    public static <E> Page<E> getPage(){
        HttpServletRequest request = request();
        if(request == null){
            Page<E> page = new PageCustom<E>(1,10);
            return page;
        }
        String pageSize = request.getParameter("pageSize");
        String pageNum = request.getParameter("pageNo");
        if(pageSize == null){
            throw new RuntimeException("分页参数未传入，如果使用的是request body，暂不支持request body方式传递分页参数。");
        }
        Page<E> page = new PageCustom<E>(Integer.parseInt(pageNum),Integer.parseInt(pageSize));
        return page;
    }
    public static HttpServletResponse response(){
        return CurrentHttpRequestFilter.getCurrentHttp().second;
    }

    /**
     * 向page对象中添加额外参数。
     * @param page
     * @param key
     * @param object
     */
    public static void addParamToPage(Page page,String key,Object object){
       if(page instanceof PageCustom){
           ((PageCustom)page).addParam(key,object);
       }
    }
}
